package flock

import (
	"fmt"
	"os"
	"syscall"
)

/*
	1、flock 属于建议性锁，不具备强制性。
	2、一个进程使用 flock 将文件锁住，另一个进程可以直接操作正在被锁的文件
	3、flock 只是用于检测文件是否被加锁，内核不会阻止其他进程的写入操作，也就是建议性锁的内核处理策略。


*/

//文件锁
type FileLock struct {
	dir string
	f   *os.File
}

func NewFLock(dir string) *FileLock {
	return &FileLock{
		dir: dir,
	}
}

//加锁
func (l *FileLock) Lock() error {
	f, err := os.Open(l.dir)
	if err != nil {
		return err
	}
	l.f = f
	err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
	if err != nil {
		return fmt.Errorf("cannot flock directory %s - %s", l.dir, err)
	}
	return nil
}

//释放锁
func (l *FileLock) Unlock() error {
	defer l.f.Close()
	return syscall.Flock(int(l.f.Fd()), syscall.LOCK_UN)
}
